/**
 * 获取嵌套对象中的值
 * @param obj 对象
 * @param path 路径
 * @returns 返回嵌套对象中的值
 */
export function getNestedValue(obj: Record<string, any>, path: string) {
  if (!obj || !path) return undefined;

  // 检查 obj 是否为对象
  if (typeof obj !== 'object' || obj === null) return undefined;

  // 分割路径并去除空字符串
  const keys = path.split('.').filter(Boolean);

  let result = obj;
  for (const key of keys) {
    // 检查当前值是否为 undefined 或 null
    if (result === null) return undefined;

    // 获取下一个嵌套值
    result = result[key];

    // 如果获取到 undefined 或 null，提前返回
    if (result === null) return undefined;
  }
  return result;
}

/**
 * 根据指定的键选择器函数，将数组中的元素分组
 * @param array 要分组的数组
 * @param keySelector 一个函数，用于从数组的每个元素中提取分组键
 * @returns 返回一个对象，其中键是分组键，值是具有相同键的元素数组
 */
export function groupBy<T, K extends keyof any>(
  array: T[],
  keySelector: (item: T) => K,
): Record<K, T[]> {
  // 使用数组的reduce方法来构建分组结果
  // eslint-disable-next-line unicorn/no-array-reduce
  return array.reduce(
    (result, item) => {
      // 使用键选择器函数从当前元素提取分组键
      const key = keySelector(item);
      // 如果当前键在结果对象中还不存在，则初始化为空数组
      if (!result[key]) {
        result[key] = [];
      }
      // 将当前元素添加到对应键的数组中
      result[key].push(item);
      // 返回累积的结果对象
      return result;
    },
    // 初始化结果对象为空
    {} as Record<K, T[]>,
  );
}
